package mymac.com.a3_21;

import android.animation.ValueAnimator;
import android.content.Context;
import android.support.annotation.AttrRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;

/**
 * Created by mymac on 2017/3/21.
 */

public class SlideMenu extends FrameLayout {

    //菜单view
    private View mMenuView;
    //主界面view
    private View mMainView;
    private ViewDragHelper mViewDragHelper;

    private int mWidth;
    private float mDragRange;
    public SlideMenu(@NonNull Context context) {
        super(context);
        initViews();
    }

    public SlideMenu(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initViews();
    }

    public SlideMenu(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initViews();
    }

    public void initViews(){
        mViewDragHelper = ViewDragHelper.create(this,callback);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = getMeasuredWidth();
        mDragRange = (float) (mWidth*0.7);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        //只能有两个子View，简单处理异常
        if (getChildCount() != 2){
            throw new IllegalArgumentException("只能有两个子View");
        }
        mMainView = getChildAt(1);
        mMenuView = getChildAt(0);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mViewDragHelper.processTouchEvent(event);
        return true;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return mViewDragHelper.shouldInterceptTouchEvent(ev);
    }

    private ViewDragHelper.Callback callback = new ViewDragHelper.Callback() {

        @Override
        public boolean tryCaptureView(View child, int pointerId) {
            return child == mMainView || child == mMenuView;
        }

        @Override
        public int getViewHorizontalDragRange(View child) {
            return (int) mDragRange;
        }

        @Override
        public int clampViewPositionHorizontal(View child, int left, int dx) {
            if (child == mMainView){
                if (left < 0) left = 0;
                if (left > mDragRange) left = (int) mDragRange;
            }
            return left;
        }

        @Override
        public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
            if (changedView == mMenuView){
                mMenuView.layout(0,0,mMenuView.getMeasuredWidth(),mMenuView.getMeasuredHeight());
                int newLeft = mMainView.getLeft() + dx;
                if (newLeft < 0) newLeft = 0;
                if (newLeft > mDragRange) newLeft = (int) mDragRange;
                mMainView.layout(newLeft,mMainView.getTop()+dy,mMainView.getMeasuredWidth()+newLeft,mMainView.getMeasuredHeight()+dy);
            }
            //计算滑动的百分点
            float fraction = mMainView.getLeft() / mDragRange;
            //执行伴随动画
            excuteAnim(fraction);
        }

        @Override
        public void onViewReleased(View releasedChild, float xvel, float yvel) {
            if (mMainView.getLeft() < mDragRange/2){
                //左半边
                mViewDragHelper.smoothSlideViewTo(mMainView,0,mMainView.getTop());
            } else {
                //右半边
                mViewDragHelper.smoothSlideViewTo(mMainView, (int) mDragRange,mMainView.getTop());
            }
            ViewCompat.postInvalidateOnAnimation(SlideMenu.this);
        }
    };

    private void excuteAnim(float fraction) {
        float scaleMainValues = (float) (0.9f + 0.1*(1-fraction));
        final ValueAnimator animatorMain = ValueAnimator.ofFloat(scaleMainValues,scaleMainValues);
        animatorMain.setDuration(2000).start();
        animatorMain.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float values = (float) animatorMain.getAnimatedValue();
                mMainView.setScaleX(values);
                mMainView.setScaleY(values);
            }
        });

        final ValueAnimator animatorMenuScale = ValueAnimator.ofFloat(fraction,1);
        animatorMenuScale.setDuration(2000).start();
        animatorMenuScale.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float values = (float) animatorMenuScale.getAnimatedValue();
                mMenuView.setScaleX(values);
                mMenuView.setScaleY(values);
            }
        });

        final ValueAnimator animatorMenuTranslation = ValueAnimator.ofFloat(-mMenuView.getMeasuredWidth()/1.5f*(1-fraction),0);
        animatorMenuTranslation.setDuration(2000).start();
        animatorMenuTranslation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float values = (float) animatorMenuTranslation.getAnimatedValue();
                mMenuView.setTranslationX(values);
            }
        });

        final ValueAnimator animatorMenuAlpha = ValueAnimator.ofFloat(0.3f*fraction,1f*fraction);
        animatorMenuAlpha.setDuration(1000).start();
        animatorMenuAlpha.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float values = (float) animatorMenuAlpha.getAnimatedValue();
                mMenuView.setAlpha(values);
            }
        });


    }

    @Override
    public void computeScroll() {
        if (mViewDragHelper.continueSettling(true)){
            ViewCompat.postInvalidateOnAnimation(SlideMenu.this);
        }
    }
}
